home *** CD-ROM | disk | FTP | other *** search
- ; MyMouse
- ; Input handler bit (to cut down the size of the source file)
- ; Andrew Forrest
- ;****************************************************************************
- ; Routine can't get semaphore since this causes deadlock when we try to
- ; change the parameters. For this reason, we must use only atomic variables.
- ;***************************************************************************
- ;***************************************************************************
-
- ; Takes a0=^oldEventChain; a1=^GlobalPtr; Returns d0=^newEventChain;
- ; Scratches d1, a0, a1
- ; Uses a4=^first link; a5=^global structure; d1=TimeStamp of last event
- IntRoutine: ;Start of input handler code
- pushm.l a4-a5
- lea (a0),a4 ; First link in event chain
- lea (a1),a5 ; Global Ptr
- .loop push.l a0
- bsr.s Do_Event
- pop.l a0
- move.l ie_NextEvent(a0),d0
- beq.s .end_loop
- move.l d0,a0
- bra.s .loop
- .end_loop move.l ie_TimeStamp+TV_SECS(a0),d1 ; time in seconds
- bsr Time_Outs
- move.l a4,d0
- popm.l a4-a5
- rts
-
- ;****************************************************************************
- Do_Event:
- ; Takes a0=^Event; a5=^GlobalPtr;
- ; scratches d1, a0, a1
- pushm.l a2/a6
- move.l IntBase(a5),a6
-
- ;*»» Perform SunMouse (Activate window)
- tst.l SunMouseOption(a5)
- beq.s .SkipSunMouse1
- cmp.b #IECLASS_TIMER,ie_Class(a0)
- bne.s .SkipSunMouse1
- bclr #STB_SunMouse,Status(a5)
- beq.s .SkipSunMouse1 ; Skip if already Sunned
- bsr GetWindow
- push.l a0
- move.l d0,a0
- cmp.l ib_ActiveWindow(a6),a0
- beq.s .EndSun
- just ActivateWindow
- .EndSun: pop.l a0
- .SkipSunMouse1:
-
- cmp.b #IECLASS_TIMER,ie_Class(a0)
- beq .not_key ; If it's a timer event, don't unblank
-
- ;*»» Reset screen blank
- move.l ie_TimeStamp(a0),ScreenTime(a5)
- bclr #STB_SBlanked,Status(a5)
- beq.s .SkipSRestore
- UnBkScreen
- .SkipSRestore
-
- cmp.b #IECLASS_RAWKEY,ie_Class(a0)
- bne .not_key ; skip this bit if not a key
-
-
- ;*»» Do Northgate keyboard mapping.
- tst.l NorthgateOption(a5)
- beq.s .SkipNorthgate
- lea NorthgateTable(pc),a2
- move.w ie_Code(a0),d0
- bclr #IECODEB_UP_PREFIX,d0
- .NorthgateLoop:
- move.b (a2),d1
- beq.s .EndNorthgate
- addq.l #3,a2
- cmp.b d0,d1
- bne.s .NorthgateLoop
- and.w #IECODE_UP_PREFIX,ie_Code(a0)
- move.b -2(a2),d0
- or.b d0,ie_Code+1(a0)
- move.b -1(a2),d0
- or.b d0,ie_Qualifier+1(a0)
- .EndNorthgate
- .SkipNorthgate
-
- move.w ie_Code(a0),d0
- tst.b d0
- bmi .end_event ;henceforth ignore key-ups
- btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
- bne.s .do_LAmiga
-
- ;*»» Blank mouse pointer if not a qualifier key pressed
- tst.l MouseBlank(a5)
- bmi.s .NoMBlank
- and.b #%11111000,d0 ; If raw key is 60 thru 67,
- cmp.b #$60,d0 ; ...we shouldn't blank mouse
- beq.s .NoMBlank ; ...('cos it was shift or something).
- bset #STB_DoMBlank,Status(a5)
- bsr SignalMouseBlank ; Blank mouse on keypress
- .NoMBlank bra .end_event
-
- .do_LAmiga:
- ;*»» Check for Amiga-ESC
- tst.l CmdOption(a5)
- beq .end_event
- cmp.w #KEYCODE_ESC,ie_Code(a0)
- bne .end_event
- clr.b ie_Class(a0)
- move.l CLISig(a5),d0
- bsr SignalTask
- bra .end_event
-
- .not_key:
- move.w ib_MouseX(a6),d0
- move.w ib_MouseY(a6),d1
- cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
- beq.s .do_mouse
- cmp.w CurrentX(a5),d0
- bne.s .do_mouse
- cmp.w CurrentY(a5),d1
- beq .end_event
-
- .do_mouse: move.w d0,CurrentX(a5)
- move.w d1,CurrentY(a5)
- ;*»» Restore mouse pointer if the mouse moves
- move.l ie_TimeStamp(a0),MouseTime(a5)
- btst #STB_MBlanked,Status(a5)
- bne.s .restore ; Restore mouse if we _know_ it's blanked
- move.l ib_ActiveWindow(a6),d0 ; Examine active window
- beq.s .no_restore ; Exit if no active window(!)
- move.l d0,a1
- move.l wd_Pointer(a1),d0
- cmp.l MouseChipData(a5),d0
- bne.s .no_restore ; Restore if it _turns out_ to be blanked
- .restore bclr #STB_DoMBlank,Status(a5)
- bsr SignalMouseBlank
- .no_restore
-
- ;*»» Test Sunnyness of mouse
- tst.l SunMouseOption(a5)
- beq.s .noSunMouse
- move.w ie_Qualifier(a0),d0
- and.w #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
- bne.s .noSunMouse
- cmp.w #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
- beq.s .noSunMouse
- bset #STB_SunMouse,Status(a5)
- .noSunMouse
-
- ;*»» Perform click-to-back.
- tst.l CTBOption(a5)
- beq .no_CTB
- cmp.w #IECODE_RBUTTON,ie_Code(a0)
- bne .no_CTB
- move.w ie_Qualifier(a0),d0
- btst #IEQUALIFIERB_LEFTBUTTON,d0
- beq .no_CTB
- pushm.l d2/a0-a1
- bsr GetWindow
- tst.l d0
- beq.s .end_CTB
- move.l d0,a1
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- bne.s .end_CTB
- ;Is this the only window on this screen, except for backdrop windows?
- move.l wd_WScreen(a1),a1
- move.l sc_FirstWindow(a1),a1
- .back_loop cmp.l a1,d0
- beq.s .endback_lp
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- beq.s .flipwindow
- .endback_lp move.l wd_NextWindow(a1),a1
- move.l a1,d2
- bne.s .back_loop
- bra.s .end_CTB
- .flipwindow move.l d0,a0
- just WindowToBack
- .end_CTB popm.l d2/a0-a1
- clr.b ie_Class(a0)
- bra .end_event
- .no_CTB
-
- ;*»» Perform click-to-front.
- tst.l CTF(a5)
- ble .no_CTF
- cmp.w #IECODE_LBUTTON,ie_Code(a0)
- bne .no_CTF
- btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
- bne .no_CTF ;to avoid interferring with Snap
- bsr GetWindow
- tst.l d0
- beq .no_CTF
- push.l d2
- move.l CTFB(a5),d2
- bmi.s .no_border
- move.l d0,a1
- btst #BBB_LEFT,d2
- beq.s .test_right
- .test_left move.w wd_MouseX(a1),d1
- move.b wd_BorderLeft(a1),d0
- ext.w d0
- cmp.w d0,d1
- blo.s .in_border
- .test_right btst #BBB_RIGHT,d2
- beq.s .test_top
- move.b wd_BorderRight(a1),d0
- ext.w d0
- add.w d0,d1
- cmp.w wd_Width(a1),d1
- bhs.s .in_border
- .test_top btst #BBB_TOP,d2
- beq.s .test_botto
- move.w wd_MouseY(a1),d1
- move.b wd_BorderTop(a1),d0
- ext.w d0
- cmp.w d0,d1
- blo.s .in_border
- .test_botto btst #BBB_BOTTOM,d2
- beq .end_CTF
- move.b wd_BorderBottom(a1),d0
- ext.w d0
- add.w d0,d1
- cmp.w wd_Height(a1),d1
- blo .end_CTF
- .in_border move.l a1,d0
- .no_border move.l CTF(a5),d1
- cmp.l #1,d1
- bhi.s .more_thn_1
- bsr DoWindowToFront
- bra .end_CTF
- .more_thn_1 cmp.l ClickWindow(a5),d0
- beq.s .same_win
- move.l d0,ClickWindow(a5)
- moveq #1,d0
- move.l d0,ClickCount(a5)
- bra.s .save_time
- .same_win ; Check to see whether MaxClickDelay has been exceeded. If not
- ; increment ClickCount and compare with (CTFOption). If equal, do
- ; a WindowToFront. Window under pointer in D0.
- push.l d0
- pushm.l d2-d3/a0
- move.l ClickTime+TV_SECS(a5),d0
- move.l ClickTime+TV_MICRO(a5),d1
- move.l ie_TimeStamp+TV_SECS(a0),d2
- move.l ie_TimeStamp+TV_MICRO(a0),d3
- just DoubleClick
- popm.l d2-d3/a0
- tst.l d0
- beq.s .time_exceeded
- addq.l #1,ClickCount(a5)
- move.l CTF(a5),d0
- cmp.l ClickCount(a5),d0
- bhi.s .need_more_clicks
- clr.l ClickCount(a5)
- pop.l d0
- bsr DoWindowToFront
- bra.s .end_CTF
- .time_exceeded
- moveq #1,d0
- move.l d0,ClickCount(a5)
- .need_more_clicks
- pop.l d0
- .save_time move.l ie_TimeStamp+TV_SECS(a0),ClickTime+TV_SECS(a5)
- move.l ie_TimeStamp+TV_MICRO(a0),ClickTime+TV_MICRO(a5)
- .end_CTF pop.l d2
- .no_CTF
-
- ;*»» Perform acceleration.
- tst.l Acceleration(a5)
- bmi .end_event
- move.l Threshold(a5),d0
- bpl.s .T1
- moveq #0,d0
- .T1 move.w ie_X(a0),d1
- bpl.s .PosX
- neg.w d1
- .PosX cmp.w d0,d1
- bls.s .SkipX ;below threshold
- move.l Acceleration(a5),d1
- muls.w ie_X(a0),d1
- bpl.s .SubDampX
- add.w DampingConstant(a5),d1
- bra.s .DampX
- .SubDampX sub.w DampingConstant(a5),d1
- .DampX move.w d1,ie_X(a0)
- .SkipX move.w ie_Y(a0),d1
- bpl.s .PosY
- neg.w d1
- .PosY cmp.w d0,d1
- bls.s .EndAccel
- move.l Acceleration(a5),d1
- muls.w ie_Y(a0),d1
- bpl.s .SubDampY
- add.w DampingConstant(a5),d1
- bra.s .DampY
- .SubDampY sub.w DampingConstant(a5),d1
- .DampY move.w d1,ie_Y(a0)
- .EndAccel
-
- .end_event popm.l a2/a6
- rts
-
- ;***************************************************************************
- Time_Outs: ;*»» Check for time-outs (mouse and screen blanking)
- ; Takes d1=TimeStamp seconds; a5=GlobalPtr
- ; scratches d0, d1, a0, a1
- push.l a6
- move.l IntBase(a5),a6
-
- ;*»» Check if window has changed with blanked pointer
- btst #STB_MBlanked,Status(a5)
- beq.s .EndMBW ; (Skip if not blanked)
- move.l MBlankWindow(a5),d0
- cmp.l ib_ActiveWindow(a6),d0
- beq.s .EndMBW
- bset #STB_DoMBlank,Status(a5)
- bsr SignalMouseBlank ; Blank mouse for this new window
- .EndMBW:
-
- ;*»» Check if mouse should be timed out
- tst.l MouseBlank(a5)
- ble.s .end_MBlank ; If user-mouse-blank-time=0, don't blank
- move.l d1,d0
- sub.l MouseBlank(a5),d0 ; this_time - user_pause
- tst.l MouseTime(a5)
- bne.s .else_MBlnk ; If last-used mouse time is zero, then
- move.l d1,MouseTime(a5) ; reset last-used mouse time
- bra.s .end_MBlank ; else
- .else_MBlnk sub.l MouseTime(a5),d0 ; sub last mouse move time
- blo.s .end_MBlank ; If this_time - last_move > user_pause
- move.l d0,MouseTime(a5)
- bset #STB_DoMBlank,Status(a5)
- bsr SignalMouseBlank
- .end_MBlank ;endif
-
- tst.l ScreenBlank(a5)
- ble.s .end_SBlank ; If screen-blank time-out=0, don't blank
- move.l d1,d0
- sub.l ScreenBlank(a5),d0 ; this_time - user_pause
- tst.l ScreenTime(a5)
- bne.s .else_SBlnk ; If last-used screen time is zero then
- move.l d1,ScreenTime(a5) ; reset last-used screen time
- bra.s .end_SBlank ;else
- .else_SBlnk sub.l ScreenTime(a5),d0
- blo.s .end_SBlank
- bset #STB_SBlanked,Status(a5)
- bne.s .end_SBlank ; Don't blank if already blanked
- BlankScreen
- .end_SBlank ;endif
-
- pop.l a6
- rts
-
- ;****************************************************************************
-
- SignalMouseBlank: ; Takes a5=GlobalPtr; Returns, Trashes nil
- push.l d0
- move.l MouseBlankSig(a5),d0
- bsr.s SignalTask
- pop.l d0
- rts
-
- SignalTask: ; Takes a5=GlobalPtr; d0=signal; Trashes nil
- pushm.l d0-d1/a0-a1/a6
- move.l Task(a5),a1
- move.l Execbase,a6
- just Signal
- popm.l d0-d1/a0-a1/a6
- rts
-
-
- ;****************************************************************************